package com.ostrich.cloud.ostrichUserService.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ostrich.cloud.common.result.PageResult;
import com.ostrich.cloud.common.result.Result;
import com.ostrich.cloud.ostrichPermission.client.PermissionClient;
import com.ostrich.cloud.ostrichPermission.client.param.AddUserParam;
import com.ostrich.cloud.ostrichPermission.client.param.UpdateUserStatusParam;
import com.ostrich.cloud.ostrichUserService.common.CustomerResultCode;
import com.ostrich.cloud.ostrichUserService.common.RoleLevel;
import com.ostrich.cloud.ostrichUserService.common.exception.CusException;
import com.ostrich.cloud.ostrichUserService.common.stateEnum.CluStateEnum;
import com.ostrich.cloud.ostrichUserService.common.stateEnum.RiderStateEnum;
import com.ostrich.cloud.ostrichUserService.common.utils.Algorithm;
import com.ostrich.cloud.ostrichUserService.infra.mapper.RiderMapper;
import com.ostrich.cloud.ostrichUserService.infra.mapper.UserParentMapper;
import com.ostrich.cloud.ostrichUserService.infra.model.Rider;
import com.ostrich.cloud.ostrichUserService.infra.model.UserParent;
import com.ostrich.cloud.ostrichUserService.service.RiderService;
import com.ostrich.ostrichUserService.dto.RiderDto;
import com.ostrich.ostrichUserService.dto.bussiness.BusinessmanDto;
import com.ostrich.ostrichUserService.param.LoginCusParam;
import com.ostrich.ostrichUserService.param.rider.RegRider;
import com.ostrich.ostrichUserService.param.rider.UpdateRider;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.GeoUnit;
import org.redisson.api.RGeo;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;

/**
 * <p>
 * 骑手表 服务实现类
 * </p>
 *
 * @author Lucas
 * @since 2022-10-26
 */
@Service
@Slf4j
public class RiderServiceImpl extends ServiceImpl<RiderMapper, Rider> implements RiderService {

    private static  String KEY = "harvest";

    private static String RIDER_ADDRESS="riderAddress";
    @Resource
    private RiderMapper riderMapper;

    @Resource
    private PermissionClient permissionClient;

    @Resource
    private UserParentMapper userParentMapper;

    @Resource
    private RedissonClient redissonClient;

    @Override
    public void riderRegister(RegRider rider) {
        AddUserParam addUserParam = new AddUserParam();
        addUserParam.setUsername(rider.getUsername());
        addUserParam.setPassword(rider.getPassword());
        addUserParam.setRoleId(RoleLevel.RIDER);
        Result result = permissionClient.addUser(addUserParam);
        Integer parentId = (Integer)result.getData();

        Rider rider1 = BeanUtil.copyProperties(result, Rider.class);

        rider1.setParentId(parentId);
        rider1.setRiderStatus(RiderStateEnum.NORMAL.getCode());
        rider1.setRiderMoney(BigDecimal.ZERO);
        rider1.setCreateTime(new Date());
        riderMapper.insert(rider1);
    }

    @Override
    public void updateRiderState(Integer riderId, String status) {
        UpdateUserStatusParam updateUserStatusParam = new UpdateUserStatusParam();

        Rider rider = riderMapper.selectById(riderId);
        updateUserStatusParam.setParentId(rider.getParentId());
        updateUserStatusParam.setStatus(status);
        permissionClient.UpdateUserStatus(updateUserStatusParam);

        int update = riderMapper.update(null, new UpdateWrapper<Rider>().eq("rider_id", riderId)
                .set("rider_status", status));
        if (update==0){
            throw new CusException("用户信息异常",1010);
        }
    }

    @Override
    public UserParent businessmanLogin(LoginCusParam lo) {
        QueryWrapper<UserParent> query = new QueryWrapper<>();
        query.eq("username",lo.getUsername())
                .eq("password", Algorithm.md5(lo.getPassword()));
        UserParent userParent = userParentMapper.selectOne(query);
        if (userParent==null){
            throw new CusException(CustomerResultCode.PASSWORD_EXCEPTION);
        }
        if(CluStateEnum.CANCEL.getCode().equals(userParent.getStatus())){
            throw new CusException(CustomerResultCode.CANCEL_EXCEPTION);
        }

        return userParent;
    }

    @Override
    public  PageResult<RiderDto> getSAllRider(Integer current, Integer size, String status,Integer businessmanId) {
        PageResult<RiderDto> pageResult = new PageResult<>();
        Page<RiderDto> page = new Page<>(current,size);

        IPage<RiderDto> allBusiness = riderMapper.getSAllRider(page, status,businessmanId);



        pageResult.setElements(allBusiness.getRecords());

        log.info("当前页{}",allBusiness.getCurrent());
        pageResult.setPage(allBusiness.getCurrent());

        log.info("每页的大小{}",allBusiness.getSize());
        pageResult.setPageSize(allBusiness.getSize());

        log.info("总数{}",allBusiness.getTotal());
        pageResult.setTotal(allBusiness.getTotal());

        log.info("总的页数{}",allBusiness.getPages());
        pageResult.setTotalPage(allBusiness.getPages());


        return pageResult;
    }

    @Override
    @Transactional
    public void addMoney(Integer riderId, Double money) {
        Rider rider = riderMapper.selectById(riderId);
        UpdateWrapper<Rider> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("rider_id",riderId)
                .set("rider_money",rider.getRiderMoney().add(BigDecimal.valueOf(money)));
        riderMapper.update(null,updateWrapper);

    }

    @Override
    public Double getCustomerLocByRider(String latitude, String logitud, Integer customerLocationId) {

        RGeo<Object> geo = redissonClient.getGeo(KEY);
        long add = geo.add(Double.parseDouble(latitude), Double.parseDouble(logitud), RIDER_ADDRESS);
        Double dist = geo.dist(customerLocationId, RIDER_ADDRESS, GeoUnit.KILOMETERS);
        RScoredSortedSet<Object> scoredSortedSet = redissonClient.getScoredSortedSet(KEY);
        boolean remove = scoredSortedSet.remove(RIDER_ADDRESS);
        if (remove){
            return dist;
        }else {
            throw new CusException("获取到收获地址距离异常",1011);
        }
    }

    @Override
    public void updateRider(Rider updateRider) {
        UpdateWrapper<Rider> riderUpdateWrapper = new UpdateWrapper<>();
        riderUpdateWrapper.eq("parent_id",updateRider.getParentId())
                .set(updateRider.getPhoneNumber()!=null,"phone_number",updateRider.getPhoneNumber())
                .set(updateRider.getBankNumber()!=null,"bank_number",updateRider.getBankNumber())
                .set(updateRider.getIdentityNumber()!=null,"identity_number",updateRider.getIdentityNumber())
                ;
        riderMapper.update(null,riderUpdateWrapper);
    }
}
